{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "4e32ee57-617a-4db1-9364-0a257c05cbd5",
   "metadata": {},
   "source": [
    "# Lesson 2: Using a String Template\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7ca54e33-87ea-4c68-96ed-20f749849ee5",
   "metadata": {},
   "source": [
    "#### Setup\n",
    "Set the MakerSuite API key with the provided helper function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "55115bf7-e3dc-4969-861f-fdc3af034b61",
   "metadata": {
    "height": 64
   },
   "outputs": [],
   "source": [
    "import os\n",
    "from utils import get_api_key\n",
    "import google.generativeai as palm\n",
    "from google.api_core import client_options as client_options_lib\n",
    "\n",
    "palm.configure(\n",
    "    api_key=get_api_key(),\n",
    "    transport=\"rest\",\n",
    "    client_options=client_options_lib.ClientOptions(\n",
    "        api_endpoint=os.getenv(\"GOOGLE_API_BASE\"),\n",
    "    )\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fd4644b0-dc5e-4759-9dbd-a936b628e331",
   "metadata": {},
   "source": [
    "#### Pick the model that generates text"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "64429b22-86cb-4fd0-b0e7-03c31db454c0",
   "metadata": {
    "height": 64
   },
   "outputs": [],
   "source": [
    "models = [m for m in palm.list_models() if 'generateText' in m.supported_generation_methods]\n",
    "model_bison = models[0]\n",
    "model_bison"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2e285ad3-a650-4a3a-91e1-66b86404a637",
   "metadata": {},
   "source": [
    "#### Helper function to call the PaLM API"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e4b61124-1a3a-4a01-ab21-ceb76ab51f95",
   "metadata": {
    "height": 149
   },
   "outputs": [],
   "source": [
    "from google.api_core import retry\n",
    "@retry.Retry()\n",
    "def generate_text(prompt, \n",
    "                  model=model_bison, \n",
    "                  temperature=0.0):\n",
    "    return palm.generate_text(prompt=prompt,\n",
    "                              model=model,\n",
    "                              temperature=temperature)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3ce7f8dd-e34b-4ff2-af4f-df6f427f1350",
   "metadata": {},
   "source": [
    "#### Prompt template\n",
    "\n",
    "1. priming: getting the LLM ready for the type of task you'll ask it to do.\n",
    "2. question: the specific task.\n",
    "3. decorator: how to provide or format the output."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2efa45aa-c151-4200-96ac-25609b294e12",
   "metadata": {
    "height": 166
   },
   "outputs": [],
   "source": [
    "prompt_template = \"\"\"\n",
    "{priming}\n",
    "\n",
    "{question}\n",
    "\n",
    "{decorator}\n",
    "\n",
    "Your solution:\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a66e2061-4716-43de-aaf4-4d10603637d0",
   "metadata": {
    "height": 30
   },
   "outputs": [],
   "source": [
    "priming_text = \"You are an expert at writing clear, concise, Python code.\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "46a991b1-0d1a-41c5-94d6-d1d32ee56367",
   "metadata": {
    "height": 30
   },
   "outputs": [],
   "source": [
    "question = \"create a doubly linked list\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b0996f20-b295-49e8-b5cf-bd33c48e422b",
   "metadata": {},
   "source": [
    "#### Observe how the decorator affects the output\n",
    "- In other non-coding prompt engineering tasks, it's common to use \"chain-of-thought prompting\" by asking the model to work through the task \"step by step\".\n",
    "- For certain tasks like generating code, you may want to experiment with other wording that would make sense if you were asking a developer the same question.\n",
    "\n",
    "In the code cell below, try out option 1 first, then try out option 2."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f8faaba4-c92f-4801-a9b9-022eb76eb456",
   "metadata": {
    "height": 98
   },
   "outputs": [],
   "source": [
    "# option 1\n",
    "# decorator = \"Work through it step by step, and show your work. One step per line.\"\n",
    "\n",
    "# option 2\n",
    "decorator = \"Insert comments for each line of code.\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f63ce784-232e-4c5c-bf0f-9ccf9ae3d398",
   "metadata": {
    "height": 64
   },
   "outputs": [],
   "source": [
    "prompt = prompt_template.format(priming=priming_text,\n",
    "                                question=question,\n",
    "                                decorator=decorator)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4a234a42-f28d-41fc-b515-288d6a1f6292",
   "metadata": {},
   "source": [
    "#### review the prompt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4ba7d0f9-6f29-4b66-811f-1471ad71af9a",
   "metadata": {
    "height": 30
   },
   "outputs": [],
   "source": [
    "print(prompt)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6ce3b6a6-5e1e-4efb-8b65-baa0319d7819",
   "metadata": {},
   "source": [
    "#### Call the API to get the completion"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ac8a5609-0a1f-4bde-a3fe-a71a3bf2c817",
   "metadata": {
    "height": 47
   },
   "outputs": [],
   "source": [
    "completion = generate_text(prompt)\n",
    "print(completion.result)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ae74f9f7-4841-4aa5-b330-a5ecff37495f",
   "metadata": {},
   "source": [
    "#### Try another question"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e9f66bd1-d90e-40d5-aebc-fbfd42c7b52f",
   "metadata": {
    "height": 47
   },
   "outputs": [],
   "source": [
    "question = \"\"\"create a very large list of random numbers in python, \n",
    "and then write code to sort that list\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bf06894e-db10-4c4e-b497-35e3ce5bb41e",
   "metadata": {
    "height": 64
   },
   "outputs": [],
   "source": [
    "prompt = prompt_template.format(priming=priming_text,\n",
    "                                question=question,\n",
    "                                decorator=decorator)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "84ed0d49-316f-445c-8e26-354ed5179654",
   "metadata": {
    "height": 30
   },
   "outputs": [],
   "source": [
    "print(prompt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cc502d78-8a16-48c4-a3d9-a1c59ff6d8cb",
   "metadata": {
    "height": 47
   },
   "outputs": [],
   "source": [
    "completion = generate_text(prompt)\n",
    "print(completion.result)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "112e9093-acbb-4d60-a278-2fdf09c8cd00",
   "metadata": {},
   "source": [
    "#### Try out the generated code\n",
    "- Debug it as needed.  For instance, you may need to import `random` in order to use the `random.randint()` function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2353bcf3-9d68-49f6-a6d3-3c807b08b8f9",
   "metadata": {
    "height": 64
   },
   "outputs": [],
   "source": [
    "# copy-paste some of the generated code that generates random numbers\n",
    "random_numbers = [random.randint(0, 100) for _ in range(100000)]\n",
    "print(random_numbers)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "346cb199-97a6-46e4-9a59-359bd7efd1b9",
   "metadata": {
    "height": 30
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
